#!/usr/bin/env python3
# bmp2rgb565_h.py
import argparse
from pathlib import Path
from PIL import Image
import numpy as np

def bmp_to_rgb565_h(bmp_path: Path, h_path: Path, var_prefix: str = 'gImage'):
    """
    把 BMP 转成 RGB565 并写入 .h 头文件
    """
    img = Image.open(bmp_path)
    if img.mode != 'RGB':
        img = img.convert('RGB')

    rgb = np.asarray(img)
    h, w = rgb.shape[:2]
    r = rgb[..., 0].astype(np.uint32)
    g = rgb[..., 1].astype(np.uint32)
    b = rgb[..., 2].astype(np.uint32)

    rgb565 = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)
    rgb565 = rgb565.astype(np.uint16)

    # 小端：低字节在前
    #byte_arr = rgb565.byteswap().tobytes()
    byte_arr = rgb565.tobytes()

    var_name = f'{var_prefix}_{bmp_path.stem}'
    guard = f'{var_name.upper()}_H'

    with h_path.open('w', encoding='utf-8') as f:
        f.write(f'#pragma once\n\n'
                f'#define {var_name.upper()}_W     {w}u\n'
                f'#define {var_name.upper()}_H     {h}u\n'
                f'#define {var_name.upper()}_BYTES {len(byte_arr)}u\n\n'
                f'const uint8_t {var_name}[{len(byte_arr)}] = {{\n')
        # 每行 16 字节
        for i in range(0, len(byte_arr), 16):
            chunk = byte_arr[i:i+16]
            hex_str = ', '.join(f'0x{b:02X}' for b in chunk)
            f.write(f'    {hex_str},\n')
        f.seek(f.tell() - 2)  # 去掉最后一个逗号
        f.write('\n};\n\n'
                f'// 16-bit 访问别名（可选）\n'
                f'// const uint16_t *{var_name}_16 = (const uint16_t *){var_name};\n')
    print(f'已生成 {h_path}  ({len(byte_arr)} bytes, {w}x{h}, RGB565 little-endian)')


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='BMP -> RGB565 .h 头文件生成器')
    parser.add_argument('bmp', help='输入 BMP 文件')
    parser.add_argument('-o', '--output', help='输出 .h 路径（默认同名.h）')
    parser.add_argument('-n', '--name', default='gImage', help='变量名前缀')
    args = parser.parse_args()

    bmp = Path(args.bmp)
    h_file = Path(args.output) if args.output else bmp.with_suffix('.h')
    bmp_to_rgb565_h(bmp, h_file, args.name)
